package myjava.casting;

public class Root1 {

   public static void main(String[] args) {

      Animal a = new Animal();
      Dog d = new Dog();

      /* downcasting : se e' all'interno di una catena di inheritance te
         lo lascia fare anche se fallimentare in future terms!
         compila ma fallisce a runtime - ClassCastException */
      // Dog ad = (Dog) a;
      // ad.bark();

      /* mentre l'upcasting e' banalmentre sempre possibile ma restringe
         le possibilita' d'uso dell'oggetto */
      Animal da = (Animal) d;
      // ma avresti potuto scrivere semplicemente
      // Animal da = d;
      da.eat();
      // this won't work anymore
      // da.bark();

      // ma comunque java sa con quale tipo di istanza ha a che fare ... infatti
      System.out.println(da instanceof Dog);

      // [RICORDA] la JVM esegue sempre la versione overridata del metodo. In questo caso esegue l'eat di Dog
   }
}

class Animal {

   public void eat() {
      System.out.println("animal is eating");
   }
}

class Dog extends Animal {

   @Override
   public void eat() {
      System.out.println("dog is eating");
   }

   public void bark() {
      System.out.println("bau bau!");
   }
}